package com.railway.switchs.aspect;

import com.alibaba.fastjson.JSONObject;
import com.railway.switchs.domain.dto.log.OperatorLog;
import com.railway.switchs.enums.EnumOperatorResult;
import com.railway.switchs.service.log.IOperatorLogService;
import com.railway.switchs.utils.IpAddressUtil;
import com.railway.switchs.utils.ServeltUtil;
import com.railway.switchs.utils.UserUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Map;


/**
 * 操作日志切面
 * @ClassName OperLogAspect
 * @Author 魏梓晟
 * @Version 1.0
 **/
@Component
@Aspect
public class OperatorLogAspect {

    @Autowired
    private IOperatorLogService operatorLogService;

    @Around("@annotation(com.railway.switchs.aspect.OperationLog)")
    public Object aroundMethod(ProceedingJoinPoint pjd) throws Throwable {
        try {
            Object proceed = pjd.proceed();
            insertOperLog(pjd, proceed,null);
            return proceed;
        } catch (Throwable e) {
            insertOperLog(pjd,null, e);
            throw e;
        }
    }

    @Async
    protected void insertOperLog(final ProceedingJoinPoint pjd, Object result, final Throwable e) {

        String userAccount = UserUtil.getUserAccount();
        String ip = IpAddressUtil.getIpAddr(ServeltUtil.getRequest());
        OperatorLog operatorLog = new OperatorLog();

        operatorLog.setOperatorAccount(userAccount);

        OperationLog operationLog = getOperationLog(pjd);

        operatorLog.setOperatorBillType(operationLog.billType());

        operatorLog.setOperatorType(operationLog.actionType());
        String params = getInParams();
        operatorLog.setOperatorParms(params);
        operatorLog.setOperatorResult(EnumOperatorResult.SUCCESS.getCode());
        if (e != null) {
            operatorLog.setOperatorResult(EnumOperatorResult.ERROR.getCode());
        }
        operatorLogService.add(operatorLog);
    }

    /**
     * 获取日志注解
     *
     * @param pjd
     * @return
     */
    private OperationLog getOperationLog(ProceedingJoinPoint pjd) {
        Signature signature = pjd.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();

        if (method != null) {
            return method.getAnnotation(OperationLog.class);
        }
        return null;
    }

    /**
     * 获取请求入参
     *
     * @return
     */
    public String getInParams() {
        Map<String, String[]> map = ServeltUtil.getRequest().getParameterMap();
        String params = JSONObject.toJSONString(map);
        return params;
    }
}
